﻿// Collapser reacts to browser events to show or hide target component(s)
define([
    'Xjs/core/util',
    'Xjs/ui/Control'
],
function (util, Control) {
    'use strict';

    var type = 'collapser',
    Collapser = Xjs.getType(type);

    if (Collapser) { // It has been already loaded
        return Collapser;
    }

    Collapser = util.define({
        base: Control,
        construct: function (conf, parent) {
            Collapser.base.constructor.call(this, conf, parent);

            this.collapsed = conf.collapsed; // Whether it is initially collapsed
            this.collapsedCls = conf.collapsedCls || 'w-collapsed';
            this.expandedCls = conf.expandedCls || 'w-expanded';

            // Add the event handlers
            this.beforeCollapse = conf.beforeCollapse;
            this.onCollapse = conf.onCollapse;

            this.beforeExpand = conf.beforeExpand;
            this.onExpand = conf.onExpand;

            // Add the items to be collapsed/expanded
            this.targets = conf.targets || [];

            // Ensure these targets have ids so they can be shown/hidden using the DOM
            if (this.targets) {
                this.targets.forEach(function (t) {
                    t.ensureId();
                });
            }

        },
        type: type,
        tag: 'div',
        cls: 'w-tool w-selectable',
        requiresId: true, // Needs to change class to collapsed or expanded

        addTarget: function (cmp) {
            cmp.ensureId();
            this.targets.push(cmp);
        },

        // Shows this control in a collapsed way and hides the children components of this collapser
        collapse: function () {
            if (!this.collapsed) {

                if (this.beforeCollapse) {
                    if (this.beforeCollapse.apply(this) === false) {
                        return; // Cancel collapsing
                    }
                }

                this.collapsed = true;

                if (this.rendered) {
                    this.updateClass();
                    this.hideTargets();

                    if (this.onCollapse) {
                        this.onCollapse.apply(this);
                    }
                }
            }
        },

        // Shows this control in a expanded way and shows the children components of this collapser
        expand: function () {
            if (this.collapsed) {

                this.collapsed = false;

                if (this.beforeExpand) {
                    if (this.beforeExpand.apply(this) === false) {
                        return; // Cancel collapsing
                    }
                }

                if (this.rendered) {
                    this.updateClass();
                    this.showTargets();

                    if (this.onExpand) {
                        this.onExpand.apply(this);
                    }
                }
            }
        },

        showTargets: function () {

            if (!this.targets) {
                return;
            }

            this.targets.forEach(function (c) {
                c.show();
            });
        },

        hideTargets: function () {

            if (!this.targets) {
                return;
            }

            this.targets.forEach(function (c) {
                c.hide();
            });
        },

        updateClass: function () {
            if (this.collapsed) {
                this.replaceClass(this.expandedCls, this.collapsedCls);
            }
            else {
                this.replaceClass(this.collapsedCls, this.expandedCls);
            }
        },

        // If it is collapsed the expand it, collapse it otherwise
        toggle: function () {
            if (this.collapsed) {
                this.expand();
            }
            else {
                this.collapse();
            }
        },

        onRender: function () {

            Collapser.base.onRender.call(this);

            var me = this;

            // Set the class according to the initial state
            me.updateClass();

            if (me.collapsed) {
                me.hideTargets();
            }
            else {
                me.showTargets();
            }

            // Enable the event
            me.on('click', function () {
                me.toggle();
            });
        }
    });

    Xjs.registerType(Collapser);

    return Collapser;
});